﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#include "GcmpDatabaseInterface.h"
#include "OwnerPtr.h"
#include "GbmpQuickCast.h"
#include <ios>
#include <cstdint>

namespace gcmp
{
    /// \brief 输入输出模式
    enum class IOMode : int32_t
    {
        Load = 0,   ///< 读取模式
        Store       ///< 写入模式
    };

    const std::string BLOB_VERSION = "\n#1"; //blob字段自定义版本号

    /// \brief 输入输出接口
    class GCMP_DATABASE_INTERFACE_EXPORT IIODevice
    {
        DEFINE_CAST_BASE(gcmp::IIODevice)
    public:
        /// \brief 创建加载用内存IO设备
        /// \param pBuffer buffer首地址
        /// \param nBufferSize buffer大小
        /// \return OwnerPtr<IIODevice> 创建出的IODevice
        static OwnerPtr<IIODevice> CreateMemoryIODeviceForLoad(char * pBuffer, uint64_t nBufferSize);

        /// \brief 创建存储用内存IO设备，调用方提供缓存。
        /// \param pBuffer buffer首地址
        /// \param nBufferSize buffer大小
        /// \return OwnerPtr<IIODevice> 创建出的IODevice
        static OwnerPtr<IIODevice> CreateMemoryIODeviceForStore(char * pBuffer, uint64_t nBufferSize);

        /// \brief 创建存储用内存IO设备。
        /// \param pBuffer buffer首地址
        /// \param nBufferSize buffer大小
        /// \return OwnerPtr<IIODevice> 创建出的IODevice
        static OwnerPtr<IIODevice> CreateMemoryIODeviceForStore();

        /// \brief  是否是Load模式
        /// \return bool 是Load模式返回true，否则返回false
        virtual bool IsLoading() const = 0;

        /// \brief  输入输出字节流是否已经打开
        /// \return bool 打开返回true，否则返回false
        virtual bool IsOpened() const = 0;

        /// \brief 获取当前读写的字节流位置
        /// \return uint64_t 当前读写的字节流位置
        virtual uint64_t Pos() = 0;

        /// \brief 写入指定长度的字节流
        /// \param p 要写入的数据指针
        /// \param nLen 要写入的数据长度
        /// \return void
        virtual void Write(const void *p , uint64_t nLen) = 0;

        /// \brief 读取指定长度的字节流
        /// \param p 存放读取数据的指针
        /// \param nLen 读取数据的长度
        /// \return uint64_t 读取成功返回读取数据的长度，否则返回0
        virtual uint64_t Read(void *p, uint64_t nLen) = 0;

        /// \brief  定位到指定的字节流位置
        /// \param nPos 指定的字节流位置
        /// \return void
        virtual void Seek(uint64_t nPos) = 0;

        /// \brief  根据指定方式定位到指定字节位置
        /// \param nOff 指定的字节位置
        /// \param way 指定的定位方式
        /// \return void
        virtual void Seek(int64_t nOff, std::ios_base::seekdir way) = 0;

        /// \brief 打开字节流
        /// \return bool 成功打开返回true，否则返回false
        virtual bool Open() = 0;

        /// \brief 关闭字节流
        /// \return void
        virtual void Close() = 0;

        /// \brief 将字节流信息重置到默认值
        /// \return void
        virtual void Reset() = 0;

        /// \brief 获取设备数据的缓冲区
        /// \return 缓冲区的指针
        virtual const char * GetData() const = 0;

        /// \brief 获取设备数据的缓冲区
        /// \return 缓冲区的指针
        virtual char * GetData() = 0;

        /// \brief 获取设备数据的大小
        /// \return uint64_t 设备数据的大小
        virtual uint64_t GetDataSize() const = 0;

    public:
        /// \brief 析构函数
        virtual ~IIODevice() = 0;
    };
}
